﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Collections.ObjectModel;
using System.Xml;
using System.Xml.XPath;
using System.Reflection;


using log4net;
using CommonLib;

namespace ConfigUtilLib
{
   

    public class FetcherConfigReader
    {
        private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        private const string InterfaceStr = "CommonLib.FetcherInterface";

        public FetcherConfigReader()
        {
            
        }

        /// <summary>
        /// Read fetcher Config Record ,  Giving control for User Plugin Code as well to read Fetcher..
        /// </summary>
        /// <param name="fetcherBinRec"></param>
        /// <param name="fetcherNode"></param>
        /// <returns></returns>
        public static FetcherConfigBaseRec GetConfiguration(FetcherAndProcessorBin fetcherBinRec, XmlNode fetcherNode)
        {
            Log.DebugFormat(" Configuration reading by {0}  , DLL is {1} ", fetcherBinRec.Type, fetcherBinRec.Dll );

            // Loop thru Everey Process Object 
               Assembly reflectionAssembly = null;
               FetcherConfigBaseRec fetcherConfig = null;
                
                try
                {
                    // 1. Load Library 
                    reflectionAssembly = Assembly.LoadFrom(fetcherBinRec.Dll);
                }
                catch (Exception e)
                {
                    Log.DebugFormat("Unable to Load DLL : {0} : {1}", fetcherBinRec.Dll, e.Message);
                    return null;
                }

                if (reflectionAssembly == null)  return null;

                foreach (var classType in reflectionAssembly.GetTypes())
                {

                    // 2. Verify Credentials  

                    if ((classType == null) || (classType.IsClass != true) || (classType.GetInterface(InterfaceStr) == null))
                    {
                        continue;
                    }

                    // if all good Invoke The method 
                    var ibaseObject = Activator.CreateInstance(classType) as FetcherInterface;
                    Log.DebugFormat("......Dynamically Invoking compute() on {0} Class  ", classType.FullName);

                    
                    // Kick it off in a Thread.. 
                    if (ibaseObject != null) fetcherConfig = ibaseObject.getConfiguration(fetcherNode);
                }

                return fetcherConfig;
            
        }
    }
}
